package ZipList;

public class ZipList {
    private ZipListEntry[] entries; // 使用数组存储的元素
    private int capacity; // 数组的容量
    private int size; // 当前元素的数量

    public ZipList(int initCapacity) {
        this.entries = new ZipListEntry[initCapacity];
        this.capacity = initCapacity;
        this.size = 0;
    }

    // 插入
    public void insert(byte[] data) {
        // 如果数组已满，则扩容
        extracted();

        // 插入新元素
        entries[size++] = new ZipListEntry(data);
    }

    // 提供将值和分数放置在ZipList相邻位置，根据分数进行插入排序
    public void insert(byte[] dataBytes, byte[] scoreBytes) {
        // 如果数组已满，则扩容
        extracted();

        double score = bytesToDouble(scoreBytes);
        int workIndex = 1;
        while (workIndex < size) {
            double currentScore = bytesToDouble(entries[workIndex].getData());
            if (score < currentScore) {
                break;
            }

            // 只找分数
            workIndex += 2;
        }

        // 将插入位置空出两个位置
        System.arraycopy(entries, workIndex, entries, workIndex + 2, size - workIndex);

        // 插入新元素
        entries[workIndex] = new ZipListEntry(dataBytes);
        entries[workIndex + 1] = new ZipListEntry(scoreBytes);

        // 递增元素个数
        size += 2;
    }

    // 判断容量是否已满并扩容
    private void extracted() {
        if (size >= capacity) {
            capacity *= 2;
            ZipListEntry[] newEntries = new ZipListEntry[capacity];
            System.arraycopy(entries, 0, newEntries, 0, size);
            entries = newEntries;
        }
    }

    // 将字节数组转换成double类型
    private double bytesToDouble(byte[] bytes) {
        return Double.longBitsToDouble(bytesToLong(bytes));
    }

    // 将字节数组转换成long类型
    private long bytesToLong(byte[] bytes) {
        long value = 0;
        for (int i = 0; i < 8; i++) {
            value |= ((long) bytes[i] & 0xff) << (8 * i);
        }
        return value;
    }

    // 查找
    public ZipListEntry find(int index) {
        if (index < 0 || index >= size) {
            return null;
        }
        return entries[index];
    }

    // 获取长度
    public int getSize() {
        return size;
    }

    // 获取ZipList中的全部元素
    public ZipListEntry[] getAllData() {
        ZipListEntry[] allData = new ZipListEntry[size];
        System.arraycopy(entries, 0, allData, 0, size);
        return allData;
    }
}
